package com.artup.common;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.commons.lang3.StringUtils;

import com.artup.common.cache.CacheObject;
import com.artup.util.SpringContextUtils;
import com.artup.util.date.DateUtils;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * 缓存管理类
 * @author Lomis
 *
 */
public class CacheManager {
	private static Vector<CacheObject> caches = new Vector<CacheObject>();

	private static Object locks = new ArrayList();

	private static JedisPool jedisPool;

	private static ObjectMapper objectMapper = new ObjectMapper();
	
	public CacheManager(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
		reload();
	}
	
	/**
	 * 打印消息
	 * @param paramString
	 */
	public static synchronized void printMessage(String paramString){
		
	}
	
	/**
	 * 打印消息
	 * @param paramString
	 * @param paramBoolean
	 */
	public static synchronized void printMessage(String paramString, boolean paramBoolean) {
		StringBuffer localStringBuffer = new StringBuffer(paramString);

		for (int i = paramString.length() * 2; i < 55; i++) {
			localStringBuffer.append(".");
		}

		System.out.println("信息: [" + DateUtils.formatDate(new Timestamp(System.currentTimeMillis()), "yyyy-MM-dd hh:mm:ss a") + "]" + localStringBuffer.toString() + (paramBoolean ? "[成功]" : "[失败]"));
	}
	
	/**
	 * 注册缓存数据
	 * @param paramCacheObject
	 */
	public static void register(CacheObject paramCacheObject) {
		caches.add(paramCacheObject);
		if (jedisPool == null) {
			jedisPool = SpringContextUtils.getBean("jedisPool");
		}
		Jedis jedis = jedisPool.getResource();
		System.out.println("key[" + paramCacheObject.getCacheName() + "] is have redis server = " + jedis.exists(paramCacheObject.getCacheName()));
		/*if (jedis.exists(paramCacheObject.getCacheName())) {//  如果redis服务中已存在该key,不允许再次放入
			return;
		}*/
		try {
			Object data = paramCacheObject.loadData();
			if (paramCacheObject.isList()) {
				List<?> l = (List<?>)data;
				if (l != null && l.size() > 0) {
					jedis.hset(paramCacheObject.getCacheName(), paramCacheObject.getCacheName(), objectMapper.writeValueAsString(l));
					//jedis.hset(paramCacheObject.getCacheName(), paramCacheObject.getCacheName(), (String)data);
				}
			} else {
				Map<String, String> m = (Map<String, String>)data;
				if (m != null && m.size() > 0) {
					jedis.hmset(paramCacheObject.getCacheName(), m);
				}
			}
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			jedisPool.returnResource(jedis);
		}
	}
	
	/**
	 * 重载
	 */
	public static void reload() {
		if (jedisPool == null) {
			jedisPool = SpringContextUtils.getBean("jedisPool");
		}
		Jedis jedis = jedisPool.getResource();

		synchronized (locks) {
			for (Enumeration localEnumeration = caches.elements(); localEnumeration.hasMoreElements();) {
				CacheObject localCacheObject = (CacheObject) localEnumeration.nextElement();
				jedis.hdel(localCacheObject.getCacheName(), localCacheObject.getCacheName());
				try {
					Object data = localCacheObject.loadData();
					if (localCacheObject.isList()) {
						List<?> l = (List<?>)data;
						if (l != null && l.size() > 0) {
							jedis.hset(localCacheObject.getCacheName(), localCacheObject.getCacheName(), objectMapper.writeValueAsString(l));
							//jedis.hset(paramCacheObject.getCacheName(), paramCacheObject.getCacheName(), (String)data);
						}
					} else {
						Map<String, String> m = (Map<String, String>)data;
						if (m != null && m.size() > 0) {
							jedis.hmset(localCacheObject.getCacheName(), m);
						}
					}
				} catch (JsonGenerationException e) {
					e.printStackTrace();
				} catch (JsonMappingException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally{
					jedisPool.returnResource(jedis);
				}
			}
		}
	}
	
	/**
	 * 注销缓存数据
	 * @param paramCacheObject
	 */
	public static void unRegister(CacheObject paramCacheObject) {
		if (jedisPool == null) {
			jedisPool = SpringContextUtils.getBean("jedisPool");
		}
		caches.remove(paramCacheObject);
		Jedis jedis = jedisPool.getResource();
		if (paramCacheObject.isList())
			jedis.hdel(paramCacheObject.getCacheName(), paramCacheObject.getCacheName());
		else {
			Set<String> keySet = jedis.hkeys(paramCacheObject.getCacheName());
			if (keySet != null && keySet.size() > 0) {
				String[] keys = new String[keySet.size()];
				keySet.toArray(keys);
				jedis.hdel(paramCacheObject.getCacheName(), keys);
			}
		}
		jedisPool.returnResource(jedis);
	}
	
	/**
	 * 更新缓存数据
	 * @param paramCacheObject
	 */
	public static void update (CacheObject paramCacheObject, String key, Object data) {
		if (jedisPool == null) {
			jedisPool = SpringContextUtils.getBean("jedisPool");
		}
		Jedis jedis = jedisPool.getResource();
		try {
			if (data != null) {
				if (data instanceof Map) {
					Map<String, String> map = (Map<String, String>)data;
					if (map.size()> 0) {
						jedis.hmset(paramCacheObject.getCacheName(), map);
					}
				} else if (data instanceof List){
					List<?> list = (List<?>)data;
					if (list.size() > 0) {
						jedis.hset(paramCacheObject.getCacheName(), paramCacheObject.getCacheName(), objectMapper.writeValueAsString(list));
					}
				}
			}
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			jedisPool.returnResource(jedis);
		}
	}
	
	/**
	 * 获取缓存信息
	 * @param paramCacheObject
	 * @param key
	 * @return
	 */
	public static Object getCache(CacheObject paramCacheObject, String key) {
		if (jedisPool == null) {
			jedisPool = SpringContextUtils.getBean("jedisPool");
		}
		Jedis jedis = jedisPool.getResource();
		Object obj = null;
		if (StringUtils.isBlank(key)) {
			obj = jedis.hget(paramCacheObject.getCacheName(), paramCacheObject.getCacheName());
		} else {
			obj = jedis.hget(paramCacheObject.getCacheName(), key);
		}
		jedisPool.returnResource(jedis);
		return obj;
	}
}
